{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个实例中，我们使用tensorflow来实现一个简单的手写数字识别的网络，并用这个网络来做个\n",
    "简单的识别示例。\n",
    "\n",
    "首先导入一些用到的库。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:50.515650Z",
     "start_time": "2018-06-01T06:32:43.133728Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "from matplotlib import pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "tf.logging.set_verbosity(tf.logging.INFO)\n",
    "#为将要被记录的的东西（日志）设置开始入口\n",
    "#在tensorflow中直接log打印，TensorFlow使用五个不同级别的日志消息。 \n",
    "#按照上升的顺序，它们是DEBUG，INFO，WARN，ERROR和FATAL。 在某个级别配置日志记录时，\n",
    "#TensorFlow将输出与该级别相对应的所有日志消息以及所有级别的严重级别。 \n",
    "#例如，如果设置了ERROR的日志记录级别，则会收到包含ERROR和FATAL消息的日志输出，\n",
    "#如果设置了一个DEBUG级别，则会从所有五个级别获取日志消息。\n",
    "#默认情况下，TensorFlow在WARN的日志记录级别进行配置，\n",
    "#但是在跟踪模型训练时，您需要将级别调整为INFO，这将提供操作正在进行的其他反馈。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T05:39:48.304594Z",
     "start_time": "2018-06-01T04:55:17.674707Z"
    }
   },
   "source": [
    "先来看看数据长什么样子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.075054Z",
     "start_time": "2018-06-01T06:32:50.518290Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From <ipython-input-2-a34a30334354>:1: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
      "WARNING:tensorflow:From C:\\Users\\dingdangpai\\AppData\\Roaming\\Python\\Python37\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please write your own downloading logic.\n",
      "WARNING:tensorflow:From C:\\Users\\dingdangpai\\AppData\\Roaming\\Python\\Python37\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.data to implement this functionality.\n",
      "Extracting ./train-images-idx3-ubyte.gz\n",
      "WARNING:tensorflow:From C:\\Users\\dingdangpai\\AppData\\Roaming\\Python\\Python37\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.data to implement this functionality.\n",
      "Extracting ./train-labels-idx1-ubyte.gz\n",
      "WARNING:tensorflow:From C:\\Users\\dingdangpai\\AppData\\Roaming\\Python\\Python37\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:110: dense_to_one_hot (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.one_hot on tensors.\n",
      "Extracting ./t10k-images-idx3-ubyte.gz\n",
      "Extracting ./t10k-labels-idx1-ubyte.gz\n",
      "WARNING:tensorflow:From C:\\Users\\dingdangpai\\AppData\\Roaming\\Python\\Python37\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
      "(55000, 784)\n",
      "(55000, 10)\n",
      "(5000, 784)\n",
      "(5000, 10)\n",
      "(10000, 784)\n",
      "(10000, 10)\n"
     ]
    }
   ],
   "source": [
    "mnist = input_data.read_data_sets(\"./\", one_hot=True)\n",
    "\n",
    "print(mnist.train.images.shape)\n",
    "print(mnist.train.labels.shape)\n",
    "\n",
    "print(mnist.validation.images.shape)\n",
    "print(mnist.validation.labels.shape)\n",
    "\n",
    "print(mnist.test.images.shape)\n",
    "print(mnist.test.labels.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T05:49:40.128071Z",
     "start_time": "2018-06-01T05:49:40.123888Z"
    }
   },
   "source": [
    "可以看到images里面有数量不等的图片，每张图片是28x28长度的一个一维向量(784)，\n",
    "所以用的时候需要先给它还原成28x28的二维图片。labels中则是图片对应的数字的值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.695746Z",
     "start_time": "2018-06-01T06:32:51.077167Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 16 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 8))\n",
    "#figsize:指定figure的宽和高，单位为英寸；\n",
    "\n",
    "for idx in range(16):\n",
    "    plt.subplot(4, 4, idx + 1)\n",
    "    plt.axis('off')\n",
    "    plt.title('[{}]'.format(np.argmax(mnist.train.labels[idx])))\n",
    "    plt.imshow(mnist.train.images[idx].reshape((28, 28)))\n",
    "#使用argmax是因为label在导入时已经进行了独热onehot处理。返回的是最大数的索引，表示第几维的最大值。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，定义用于训练的网络，首先定义网络的输入。\n",
    "\n",
    "这里我们直接使用上面的数据作为输入，所以定义两个placeholder分别用于图像和lable数据，另外，定义一个bool类型的变量用于标识当前网络是否正在训练。\n",
    "\n",
    "为了让网络更高效的运行，多个数据会被组织成一个batch送入网络，两个placeholder的第一个维度就是batchsize，因为我们这里还没有确定batchsize，所以第一个维度留空。\n",
    "\n",
    "placeholder是TensorFlow的占位符节点，由placeholder方法创建，是一种常量，但是由用户在调用run方法时传递，也可以将placeholder理解为一种形参，即其不像constant那样直接可以使用，需要用户传递常数值。\n",
    "X = tf.placeholder(dtype=tf.float32, shape=[144, 10], name='X')\n",
    "dtype：数据类型，必填，默认为value的数据类型，传入参数为tensorflow下的枚举值（float32，float64.......）\n",
    "shape：数据形状，选填，不填则随传入数据的形状自行变动，可以在多次调用中传入不同形状的数据\n",
    "name：常量名，选填，默认值不重复，根据创建顺序为（Placeholder，Placeholder_1，Placeholder_2.......）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.706044Z",
     "start_time": "2018-06-01T06:32:51.698913Z"
    }
   },
   "outputs": [],
   "source": [
    "x = tf.placeholder(\"float\", [None, 784], name='x')\n",
    "y = tf.placeholder(\"float\", [None, 10], name='y')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "因为我们输入的是图片展开后的一维向量，所以第一步就需要先把一维向量还原为二维的图片。\n",
    "在处理图像数据的时候总会遇到输入图像的维数不符合的情况，此时tensorflow中reshape()就很好的解决了这个问题。\n",
    "tf.reshape(tensor,shape,name=None)\n",
    "将tensor变换为参数shape形式，其中的shape为一个列表形式。-1所代表的含义是我们不用亲自去指定这一维的大小，函数会自动进行计算，但是列表中只能存在一个-1。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.719298Z",
     "start_time": "2018-06-01T06:32:51.707730Z"
    }
   },
   "outputs": [],
   "source": [
    "x_image = tf.reshape(x, [-1, 28, 28, 1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:07:36.530623Z",
     "start_time": "2018-06-01T06:07:36.522665Z"
    }
   },
   "source": [
    "-1的位置是batchsize，-1表示自动计算\n",
    "\n",
    "接下来，我们定义第一个卷积层，使用6个5X5的卷积核对输入数据进行卷积，\n",
    "padding方式选择valid，所以输出数据的宽高变为24x24,但是深度已经从原来的1变成了6。\n",
    "本层卷积的激活函数为relu。\n",
    "\n",
    "tf.nn.conv2d\n",
    "(\n",
    "   input,#需要做卷积的输入图像,它要求是一个Tensor，具有[batch_size, in_height, in_width, in_channels]这样的shape，具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数]，注意这是一个4维的Tensor，要求数据类型为float32和float64其中之一\n",
    "   filter,#指定CNN中的卷积核，它要求是一个Tensor，具有[filter_height, filter_width, in_channels, out_channels]这样的shape，具体含义是[卷积核的高度，卷积核的宽度，图像通道数，卷积核个数]，要求类型与参数input相同。第三维in_channels，就是参数input的第四维，这里是维度一致，不是数值一致。这里out_channels指定的是卷积核的个数，而in_channels说明卷积核的维度与图像的维度一致，在做卷积的时候，单个卷积核在不同维度上对应的卷积图片，然后将in_channels个通道上的结果相加，加上bias来得到单个卷积核卷积图片的结果。\n",
    "   strides,#卷积时在图像每一维的步长，一维向量\n",
    "   padding,#只能是\"SAME\",\"VALID\"其中之一\n",
    "   use_cudnn_on_gpu=None,#指定是否使用cudnn加速\n",
    "   data_format=None,#指定输入的input的格式\n",
    "   name=None\n",
    ")\n",
    "\n",
    "tf.contrib.slim.conv2d\n",
    "(\n",
    "    inputs,#需要做卷积的输入图像\n",
    "    num_outputs,#指定卷积核的个数\n",
    "    kernel_size,#用于指定卷积核的维度（卷积核的宽度，卷积核的高度）\n",
    "    stride=1,#卷积时在图像每一维的步长\n",
    "    padding='SAME',#VALID或者SAME    \n",
    "    data_format=None,#指定输入的input的格式    \n",
    "    rate=1,    \n",
    "    activation_fn=nn.relu,#用于激活函数的指定，默认的为ReLU函数    \n",
    "    normalizer_fn=None,#指定正则化函数    \n",
    "    normalizer_params=None,#指定正则化函数的参数    \n",
    "    weights_initializer=initializers.xavier_initializer(),#指定权重的初始化程序    \n",
    "    weights_regularizer=None,#权重可选的正则化程序    \n",
    "    biases_initializer=init_ops.zeros_initializer(),#指定biase的初始化程序    \n",
    "    biases_regularizer=None,#biases可选的正则化程序    \n",
    "    reuse=None,#是否共享层或者和变量    \n",
    "    variables_collections=None,#指定所有变量的集合列表或者字典    \n",
    "    outputs_collections=None,#指定输出被添加的集合    \n",
    "    trainable=True,#卷积层的参数是否可被训练    \n",
    "    scope=None#共享变量所指的variable_scope\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.764292Z",
     "start_time": "2018-06-01T06:32:51.721295Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Entity <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x000001ED3D00F940>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x000001ED3D00F940>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x000001ED3D00F940>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x000001ED3D00F940>>: AssertionError: Bad argument number for Name: 3, expecting 4\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope('conv1'):\n",
    "    C1 = tf.contrib.slim.conv2d(\n",
    "        x_image, 6, [5, 5], padding='VALID', activation_fn=tf.nn.relu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来进行stride为2的最大池化，池化后，输出深度不变，但是长宽减半，所以输出变成了12x12,深度6."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.774112Z",
     "start_time": "2018-06-01T06:32:51.766784Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Entity <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x000001ED3CF96D30>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x000001ED3CF96D30>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x000001ED3CF96D30>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x000001ED3CF96D30>>: AssertionError: Bad argument number for Name: 3, expecting 4\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope('pool1'):\n",
    "    S2 = tf.contrib.slim.max_pool2d(C1, [2, 2], stride=[2, 2], padding='VALID')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:10:16.678485Z",
     "start_time": "2018-06-01T06:10:16.671472Z"
    }
   },
   "source": [
    "接下来，我们定义第二个卷积层，使用16个5X5的卷积核对输入数据进行卷积，\n",
    "padding方式还是选择valid，输出8x8,深度为16，本层卷积的激活函数为relu。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.805912Z",
     "start_time": "2018-06-01T06:32:51.776959Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Entity <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x000001ED3E11E668>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x000001ED3E11E668>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x000001ED3E11E668>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Conv.call of <tensorflow.python.layers.convolutional.Conv2D object at 0x000001ED3E11E668>>: AssertionError: Bad argument number for Name: 3, expecting 4\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope('conv2'):\n",
    "    C3 = tf.contrib.slim.conv2d(\n",
    "        S2, 16, [5, 5], padding='VALID', activation_fn=tf.nn.relu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "再进行一次stride为2的最大池化，输出为4x4,深度16。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.814748Z",
     "start_time": "2018-06-01T06:32:51.807560Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Entity <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x000001ED3E11E470>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x000001ED3E11E470>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x000001ED3E11E470>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Pooling2D.call of <tensorflow.python.layers.pooling.MaxPooling2D object at 0x000001ED3E11E470>>: AssertionError: Bad argument number for Name: 3, expecting 4\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope('pool2'):\n",
    "    S4 = tf.contrib.slim.max_pool2d(C3, [2, 2], stride=[2, 2], padding='VALID')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "池化后的数据是3维的，这里做一个拉平的操作，将3维数据展开到1维，然后送入两层全连接，全连接隐层中神经元个数分别为120，84。\n",
    "\n",
    "Flatten用来将输入“压平”，即把多维的输入一维化，常用在从卷积层到全连接层的过渡。Flatten不影响batch的大小。\n",
    "slim.flatten(inputs,outputs_collections=None,scope=None)\n",
    "Args:\n",
    "inputs: a tensor of size [batch_size, …].\n",
    "outputs_collections: collection to add the outputs.\n",
    "scope: Optional scope for name_scope."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.856740Z",
     "start_time": "2018-06-01T06:32:51.817287Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From C:\\Users\\dingdangpai\\AppData\\Roaming\\Python\\Python37\\site-packages\\tensorflow\\contrib\\layers\\python\\layers\\layers.py:1634: flatten (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use keras.layers.flatten instead.\n",
      "WARNING:tensorflow:Entity <bound method Flatten.call of <tensorflow.python.layers.core.Flatten object at 0x000001ED3D03A0F0>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Flatten.call of <tensorflow.python.layers.core.Flatten object at 0x000001ED3D03A0F0>>: AttributeError: module 'gast' has no attribute 'Num'\n",
      "WARNING: Entity <bound method Flatten.call of <tensorflow.python.layers.core.Flatten object at 0x000001ED3D03A0F0>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Flatten.call of <tensorflow.python.layers.core.Flatten object at 0x000001ED3D03A0F0>>: AttributeError: module 'gast' has no attribute 'Num'\n",
      "WARNING:tensorflow:Entity <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x000001ED3D03A0F0>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x000001ED3D03A0F0>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x000001ED3D03A0F0>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x000001ED3D03A0F0>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING:tensorflow:Entity <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x000001ED3D041EF0>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x000001ED3D041EF0>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x000001ED3D041EF0>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x000001ED3D041EF0>>: AssertionError: Bad argument number for Name: 3, expecting 4\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope('fc1'):\n",
    "    S4_flat = tf.contrib.slim.flatten(S4)\n",
    "    C5 = tf.contrib.slim.fully_connected(\n",
    "        S4_flat, 120, activation_fn=tf.nn.relu)\n",
    "\n",
    "with tf.name_scope('fc2'):\n",
    "    F6 = tf.contrib.slim.fully_connected(C5, 84, activation_fn=tf.nn.relu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:17:39.880958Z",
     "start_time": "2018-06-01T06:17:39.869797Z"
    }
   },
   "source": [
    "###### 对特征添加一个0.6的dropout，以40%的概率丢弃特征中的某些数据，\n",
    "这样可以提高网络的推广能力，减少过拟合的可能性。\n",
    "\n",
    "需要注意的是，dropout仅在训练的时候使用，验证的时候，需要关闭dropout，\n",
    "所以验证时候的keep_prob是1.0。\n",
    "\n",
    "dropout的输出最终送入一个隐层为10的全连接层，这个全连接层即为最后的分类器。\n",
    "\n",
    "Dropout就是在不同的训练过程中随机扔掉一部分神经元。也就是让某个神经元的激活值以一定的概率p，让其停止工作，这次训练过程中不更新权值，也不参加神经网络的计算。但是它的权重得保留下来（只是暂时不更新而已），因为下次样本输入时它可能又得工作了\n",
    "\n",
    "tf.nn.dropout(\n",
    "    x,#输入tensor\n",
    "    \n",
    "    eep_prob,#float类型，每个元素被保留下来的概率，设置神经元被选中的概率,在初始化时keep_prob是一个占位符,在run时设置keep_prob具体的值\n",
    "    \n",
    "    noise_shape=None,#一个1维的int32张量，代表了随机产生“保留/丢弃”标志的shape。\n",
    "    \n",
    "    seed=None,#随机数种子。\n",
    "    \n",
    "    name=None#指定该操作的名字\n",
    " ）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.913419Z",
     "start_time": "2018-06-01T06:32:51.860766Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From <ipython-input-11-413a88f1eb86>:3: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.\n",
      "WARNING:tensorflow:Entity <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x000001ED3D04D908>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x000001ED3D04D908>>: AssertionError: Bad argument number for Name: 3, expecting 4\n",
      "WARNING: Entity <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x000001ED3D04D908>> could not be transformed and will be executed as-is. Please report this to the AutgoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: converting <bound method Dense.call of <tensorflow.python.layers.core.Dense object at 0x000001ED3D04D908>>: AssertionError: Bad argument number for Name: 3, expecting 4\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope('dropout'):\n",
    "    keep_prob = tf.placeholder(name='keep_prob', dtype=tf.float32)\n",
    "    F6_drop = tf.nn.dropout(F6, keep_prob)\n",
    "\n",
    "with tf.name_scope('fc3'):\n",
    "    logits = tf.contrib.slim.fully_connected(F6_drop, 10, activation_fn=None)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来定义loss和用于优化网络的优化器。loss计算使用了sparse_softmax_cross_entropy_with_logits,\n",
    "这样做的好处是labels可以不用手动做one_hot省了一些麻烦。这里使用了sgd优化器，学习率为0.3。\n",
    "\n",
    ">试试看，增大减小学习率，换个优化器再进行训练会发生什么。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:52.084738Z",
     "start_time": "2018-06-01T06:32:51.915376Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From <ipython-input-12-cebdf5d2e5e9>:2: softmax_cross_entropy_with_logits (from tensorflow.python.ops.nn_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "\n",
      "Future major versions of TensorFlow will allow gradients to flow\n",
      "into the labels input on backprop by default.\n",
      "\n",
      "See `tf.nn.softmax_cross_entropy_with_logits_v2`.\n",
      "\n",
      "Conv/weights:0\n",
      "INFO:tensorflow:Summary name Conv/weights:0 is illegal; using Conv/weights_0 instead.\n",
      "Conv/biases:0\n",
      "INFO:tensorflow:Summary name Conv/biases:0 is illegal; using Conv/biases_0 instead.\n",
      "Conv_1/weights:0\n",
      "INFO:tensorflow:Summary name Conv_1/weights:0 is illegal; using Conv_1/weights_0 instead.\n",
      "Conv_1/biases:0\n",
      "INFO:tensorflow:Summary name Conv_1/biases:0 is illegal; using Conv_1/biases_0 instead.\n",
      "fully_connected/weights:0\n",
      "INFO:tensorflow:Summary name fully_connected/weights:0 is illegal; using fully_connected/weights_0 instead.\n",
      "fully_connected/biases:0\n",
      "INFO:tensorflow:Summary name fully_connected/biases:0 is illegal; using fully_connected/biases_0 instead.\n",
      "fully_connected_1/weights:0\n",
      "INFO:tensorflow:Summary name fully_connected_1/weights:0 is illegal; using fully_connected_1/weights_0 instead.\n",
      "fully_connected_1/biases:0\n",
      "INFO:tensorflow:Summary name fully_connected_1/biases:0 is illegal; using fully_connected_1/biases_0 instead.\n",
      "fully_connected_2/weights:0\n",
      "INFO:tensorflow:Summary name fully_connected_2/weights:0 is illegal; using fully_connected_2/weights_0 instead.\n",
      "fully_connected_2/biases:0\n",
      "INFO:tensorflow:Summary name fully_connected_2/biases:0 is illegal; using fully_connected_2/biases_0 instead.\n"
     ]
    }
   ],
   "source": [
    "cross_entropy_loss = tf.reduce_mean(\n",
    "    tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))\n",
    "\n",
    "#tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)\n",
    "#第一个参数logits：就是神经网络最后一层的输出，如果有batch的话，它的大小就是[batchsize，num_classes]，单样本的话，大小就是num_classes\n",
    "#第二个参数labels：实际的标签，大小同上\n",
    "#具体的执行流程大概分为两步：\n",
    "#第一步是先对网络最后一层的输出做一个softmax，这一步通常是求取输出属于某一类的概率，\n",
    "#对于单样本而言，输出就是一个num_classes大小的向量（[Y1，Y2,Y3...]其中Y1，Y2，Y3...分别代表了是属于该类的概率）\n",
    "#第二步是softmax的输出向量[Y1，Y2,Y3...]和样本的实际标签做一个交叉熵\n",
    "#这个函数的返回值并不是一个数，而是一个向量，如果要求交叉熵，我们要再做一步tf.reduce_sum操作,就是对向量里面所有元素求和，最后才得到\n",
    "#如果求loss，则要做一步tf.reduce_mean操作，对向量求均值\n",
    "\n",
    "\n",
    "#正则化\n",
    "#l2_loss的参数是网络的权重\n",
    "l2_loss = tf.add_n([\n",
    "    tf.nn.l2_loss(w)\n",
    "    for w in tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)\n",
    "#取权重\n",
    "])\n",
    "#tf.add_n([p1, p2, p3....])函数是实现一个列表的元素的相加。就是输入的对象是一个列表，列表里的元素可以是向量，矩阵，\n",
    "#\n",
    "\n",
    "for w in tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES):\n",
    "    print(w.name)\n",
    "    tf.summary.histogram(w.name, w)\n",
    "#summary对权重参数进行监控记录，histogram用于矩阵，scalar用于单个数值\n",
    "    \n",
    "total_loss = cross_entropy_loss + 7e-5 * l2_loss\n",
    "#交叉熵损失与L2损失的加权\n",
    "\n",
    "tf.summary.scalar('cross_entropy_loss', cross_entropy_loss)\n",
    "tf.summary.scalar('l2_loss', l2_loss)\n",
    "tf.summary.scalar('total_loss', total_loss)\n",
    "\n",
    "optimizer = tf.train.GradientDescentOptimizer(\n",
    "    learning_rate=0.3).minimize(total_loss)\n",
    "#使用梯度下降优化器对totalloss进行优化，"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:25:56.449132Z",
     "start_time": "2018-06-01T06:25:56.438340Z"
    }
   },
   "source": [
    "需要注意的是，上面的网络，最后输出的是未经softmax的原始logits，而不是概率分布，\n",
    "要想看到概率分布，还需要做一下softmax。\n",
    "\n",
    "将输出的结果与正确结果进行对比，即可得到我们的网络输出结果的准确率。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:39:50.010829Z",
     "start_time": "2018-06-01T06:39:49.997501Z"
    }
   },
   "outputs": [],
   "source": [
    "pred = tf.nn.softmax(logits)\n",
    "#softmax的输出是概率，该样本属于各个类的概率\n",
    "\n",
    "correct_pred = tf.equal(tf.argmax(y, 1), tf.argmax(logits, 1))\n",
    "#tf.argmax(input,axis)根据axis取值的不同返回每行或者每列最大值的索引。\n",
    "\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))\n",
    "\n",
    "#reduce_mean(input_tensor,\n",
    "#                axis=None,\n",
    "#                keep_dims=False,\n",
    "#                name=None,\n",
    "#                reduction_indices=None)\n",
    "#第一个参数input_tensor： 输入的待降维的tensor;\n",
    "#第二个参数axis： 指定的轴，如果不指定，则计算所有元素的均值;\n",
    "#第三个参数keep_dims：是否降维度，设置为True，输出的结果保持输入tensor的形状，设置为False，输出结果会降低维度;\n",
    "#第四个参数name： 操作的名称;\n",
    "#第五个参数 reduction_indices：在以前版本中用来指定轴，已弃用;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "saver用于保存或恢复训练的模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:52.127795Z",
     "start_time": "2018-06-01T06:32:52.103115Z"
    }
   },
   "outputs": [],
   "source": [
    "batch_size = 100\n",
    "trainig_step = 1100\n",
    "\n",
    "saver = tf.train.Saver()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以上定义的所有操作，均为计算图，也就是仅仅是定义了网络的结构，实际需要运行的话，还需要创建一个session，并将数据填入网络中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:35:22.270272Z",
     "start_time": "2018-06-01T06:33:18.829198Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "after 100 training steps, the loss is 0.444813, the validation accuracy is 0.9016\n",
      "after 200 training steps, the loss is 0.0911886, the validation accuracy is 0.9532\n",
      "after 300 training steps, the loss is 0.0912475, the validation accuracy is 0.961\n",
      "after 400 training steps, the loss is 0.123562, the validation accuracy is 0.9702\n",
      "after 500 training steps, the loss is 0.0971936, the validation accuracy is 0.9744\n",
      "after 600 training steps, the loss is 0.0382344, the validation accuracy is 0.9734\n",
      "WARNING:tensorflow:From C:\\Users\\dingdangpai\\AppData\\Roaming\\Python\\Python37\\site-packages\\tensorflow\\python\\training\\saver.py:960: remove_checkpoint (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use standard file APIs to delete files with this prefix.\n",
      "after 700 training steps, the loss is 0.185901, the validation accuracy is 0.9728\n",
      "after 800 training steps, the loss is 0.0767628, the validation accuracy is 0.974\n",
      "after 900 training steps, the loss is 0.152463, the validation accuracy is 0.9808\n",
      "after 1000 training steps, the loss is 0.0586991, the validation accuracy is 0.9806\n",
      "the training is finish!\n",
      "the test accuarcy is: 0.9822\n"
     ]
    }
   ],
   "source": [
    "merged = tf.summary.merge_all()\n",
    "with tf.Session() as sess:\n",
    "\n",
    "    writer = tf.summary.FileWriter(\"logs/\", sess.graph)\n",
    "\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "\n",
    "    #定义验证集与测试集\n",
    "    validate_data = {\n",
    "        x: mnist.validation.images,\n",
    "        y: mnist.validation.labels,\n",
    "        keep_prob: 1.0\n",
    "    }\n",
    "    test_data = {x: mnist.test.images, y: mnist.test.labels, keep_prob: 1.0}\n",
    "\n",
    "    for i in range(trainig_step):\n",
    "        xs, ys = mnist.train.next_batch(batch_size)\n",
    "        _, loss, rs = sess.run(\n",
    "            [optimizer, cross_entropy_loss, merged],\n",
    "            feed_dict={\n",
    "                x: xs,\n",
    "                y: ys,\n",
    "                keep_prob: 0.6\n",
    "            })\n",
    "        writer.add_summary(rs, i)\n",
    "\n",
    "        #每100次训练打印一次损失值与验证准确率\n",
    "        if i > 0 and i % 100 == 0:\n",
    "            validate_accuracy = sess.run(accuracy, feed_dict=validate_data)\n",
    "            print(\n",
    "                \"after %d training steps, the loss is %g, the validation accuracy is %g\"\n",
    "                % (i, loss, validate_accuracy))\n",
    "            saver.save(sess, './model.ckpt', global_step=i)\n",
    "\n",
    "    print(\"the training is finish!\")\n",
    "    #最终的测试准确率\n",
    "    acc = sess.run(accuracy, feed_dict=test_data)\n",
    "    print(\"the test accuarcy is:\", acc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:58:16.766415Z",
     "start_time": "2018-06-01T06:58:15.918700Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From C:\\Users\\dingdangpai\\AppData\\Roaming\\Python\\Python37\\site-packages\\tensorflow\\python\\training\\saver.py:1276: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use standard file APIs to check for files with this prefix.\n",
      "INFO:tensorflow:Restoring parameters from ./model.ckpt-1000\n",
      "1.0\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 16 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "with tf.Session() as sess:\n",
    "    ckpt = tf.train.get_checkpoint_state('./')\n",
    "    if ckpt and ckpt.model_checkpoint_path:\n",
    "        saver.restore(sess, ckpt.model_checkpoint_path)\n",
    "        final_pred, acc = sess.run(\n",
    "            [pred, accuracy],\n",
    "            feed_dict={\n",
    "                x: mnist.test.images[:16],\n",
    "                y: mnist.test.labels[:16],\n",
    "                keep_prob: 1.0\n",
    "            })\n",
    "        orders = np.argsort(final_pred)\n",
    "        plt.figure(figsize=(8, 8))\n",
    "        print(acc)\n",
    "        for idx in range(16):\n",
    "            order = orders[idx, :][-1]\n",
    "            prob = final_pred[idx, :][order]\n",
    "            plt.subplot(4, 4, idx + 1)\n",
    "            plt.axis('off')\n",
    "            plt.title('{}: [{}]-[{:.1f}%]'.format(\n",
    "                np.argmax(mnist.test.labels[idx]), order, prob * 100))\n",
    "            plt.imshow(mnist.test.images[idx].reshape((28, 28)))\n",
    "\n",
    "    else:\n",
    "        pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
